package org.wyq.myweb.jmx.snapshot;

import java.util.Collection;

import javax.annotation.Resource;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
import org.wyq.myweb.jmx.beaninfo.IInfoBean;
import org.wyq.myweb.jmx.service.IMXBeanService;


@Component("snapshot")
public class SystemSnapshot implements ISystemSnapshot{
	Logger log = Logger.getLogger(this.getClass().getName());
	
	
	private ServiceChain chain;
	
	
	@Resource(name="memorymx")
	private void setMemoryService(IMXBeanService service) {
		chain(service);
	}

	@Resource(name="gcmx")
	private void setGcService(IMXBeanService service) {
		chain(service);
	}

	@Resource(name="classloadermx")
	private void setClassLoaderService(IMXBeanService service){
		chain(service);
	}
	
	@Resource(name="compilemx")
	private void setCompileService(IMXBeanService service){
		chain(service);
	}
	
	@Override
	public Collection<? extends IInfoBean> doSnapshot() {
		Collection<IInfoBean> collection  = new java.util.ArrayList<IInfoBean>();
		if(chain == null){
			log.error("chain is null, result is empty");
			return collection;
		}
		ServiceChain start = chain;
		do {
			IInfoBean infoBean = start.service.getInfoBean();
			if(infoBean != null)
				collection.add(infoBean);
		} while ((start = start.successor) != null);
		return collection;
	}

	@Override
	public String snapshotJsonString() {
		JSONObject root = new JSONObject();
		Collection<? extends IInfoBean> beans = this.doSnapshot();
		for(IInfoBean bean:beans){
			JSONObject _json = JSONObject.fromObject(bean);
			root.put(bean.name(), _json);
		}
		String jsonString = root.toString();
		if(log.isDebugEnabled())
			log.debug(jsonString);
		return jsonString;
	}
	
	private void chain(IMXBeanService service){
		chain("",service);
	}
	
	private void chain(String name,IMXBeanService service){
		if(name == null || name.length() == 0  || name.trim().length() == 0)
			name = service.getClass().getName();
		if(service == null){
			log.error("service is null");
			return;
		}
		if(chain == null)
			chain = new ServiceChain(name, service);
		else{
			ServiceChain c = chain;
			while(c.getSuccessor()!= null)
				c = c.getSuccessor();
			c.setSuccessor(new ServiceChain(name, service));
		}
	}
	
	
	class ServiceChain {
		private IMXBeanService service;
		private String name;

		private ServiceChain successor;

		ServiceChain(String name,IMXBeanService service) {
			this.name = name;
			this.service = service;
		}

		private ServiceChain setSuccessor(ServiceChain successor) {
			this.successor = successor;
			return this;
		}

		private ServiceChain getSuccessor() {
			return this.successor;
		}

	}

}
